package com.wan.data.mysql.factory;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.DbRuntimeException;
import cn.hutool.db.DbUtil;
import cn.hutool.db.dialect.DriverUtil;
import cn.hutool.db.ds.DSFactory;
import cn.hutool.db.ds.DataSourceWrapper;
import cn.hutool.setting.Setting;

import javax.sql.DataSource;

public abstract class DataSourceFactory {

    public JdbcSetting resolverSetting(String path){
        Setting config = new Setting(path);
        if (MapUtil.isEmpty(config)) {
            throw new DbRuntimeException("No config for path: [{}]", path);
        } else {
            String url = config.getAndRemoveStr(DSFactory.KEY_ALIAS_URL);
            if (StrUtil.isBlank(url)) {
                throw new DbRuntimeException("No JDBC URL for setting: [{}]", path);
            } else {
                DbUtil.removeShowSqlParams(config);
                String driver = config.getAndRemoveStr(DSFactory.KEY_ALIAS_DRIVER);
                if (StrUtil.isBlank(driver)) {
                    driver = DriverUtil.identifyDriver(url);
                }
                String user = config.getAndRemoveStr(DSFactory.KEY_ALIAS_USER);
                String pass = config.getAndRemoveStr(DSFactory.KEY_ALIAS_PASSWORD);
                return new JdbcSetting(url,driver,user,pass,config);
            }
        }
    }

    public DataSourceWrapper createDataSource(String path){
        return createDataSource(resolverSetting(path));
    }

    public DataSourceWrapper createDataSource(JdbcSetting jdbcSetting){
        return DataSourceWrapper.wrap(this.createDataSource(jdbcSetting.jdbcUrl, jdbcSetting.driver,
                jdbcSetting.user, jdbcSetting.password, jdbcSetting.setting), jdbcSetting.driver);
    }

    protected abstract DataSource createDataSource(String url, String driver, String user, String pass, Setting setting);


    public static class JdbcSetting{
        public  String jdbcUrl;
        public  String driver;
        public  String user;
        public  String password;
        public  Setting setting;

        //jdbcUrl切分成3个部分,前缀 + 数据库名 + 后缀
        // jdbc:mysql://127.0.0.1:3306/    data_test    ?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=utf8&autoReconnect=true&autoReconnectForPools=true&failOverReadOnly=false&useServerPrepStmts=true&cachePrepStmts=true&allowMultiQueries=true&rewriteBatchedStatements=true
        public String prefix;
        public String dbName;
        public String suffix;

        public JdbcSetting(String jdbcUrl, String driver, String user, String password,Setting properties) {
            this.jdbcUrl = jdbcUrl;
            this.driver = driver;
            this.user = user;
            this.password = password;
            this.setting = properties;
            String[] strings = jdbcUrl.split("[?]");
            if(strings.length != 2){
                throw new RuntimeException("数据库配置url不正确!! -> " + jdbcUrl);
            }
            suffix = "?" + strings[1];
            int index = strings[0].lastIndexOf("/") + 1;
            prefix = strings[0].substring(0,index);
            dbName = strings[0].substring(index);
        }

        public JdbcSetting(JdbcSetting jdbcSetting){
            this(jdbcSetting.jdbcUrl,jdbcSetting.driver,jdbcSetting.user,
                    jdbcSetting.password, Setting.create().addSetting(jdbcSetting.setting));
        }

        public void reconnectUrlStr(){
            this.jdbcUrl = prefix + dbName + suffix;
        }
    }

}
